# -*- encoding:UTF-8 -*-
# desc: rpm download
# created time: 20250117

import argparse
import requests
import re
import subprocess
import sys
import os
from time import sleep


def get_rpm_list(repo_url):
    """
        return: all_repos_list | rpm包列表
    """
    all_repos_list = []
    headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) \
        AppleWebKit/537.36 (KHTML, like Gecko) \
            Chrome/91.0.4472.124 Safari/537.36'
    }
    response = requests.get(repo_url, headers=headers)
    response.encoding = 'utf-8'
    if response.status_code == 200:
        response_content = response.text
        match_obj = re.findall(
            r'class="link".*<a href="(?!../)(?!https://)(.*?.rpm)"',
            response_content)
        if match_obj:
            all_repos_list += match_obj
    return all_repos_list


def check_epkg_tmp_repodir():
    """检查epkg临时repo源是否存在
        return: True | False
    """
    epkg_package_dir = os.environ.get("_epkg_repo_dir")
    mount_nginx_host = os.environ.get("mount_nginx_host")
    epkg_list = []
    epkg_url = "{0}/{1}".format(mount_nginx_host, epkg_package_dir)
    response = requests.get(epkg_url)
    if response.status_code == 200:
        match_obj = re.findall(r'<a href="(?!\.\.\/)(.*?)"')
        for child_dir in match_obj:
            url = f'{epkg_url}/{child_dir}'
            tmp_response = requests.get(url)
            tmp_response.encoding = "UTF-8"
            epkg = re.findall(r'<a href="(.*?.epkg)">', tmp_response.text)
            epkg_list.extend(epkg)
        return True, epkg_list
    else:
        # 不存在
        return False, epkg_list


def get_batch_rpm_list(rpm_list, epkg_file_list):
    """
        根据包名，版本号比对出新增的rpm包列表
        return : batch_list 
    """
    epkg_pkg_version = []
    rpm_pkg_version = []
    rpm_name_map_list = []
    batch_list = []
    for epkg_file in epkg_file_list:
        epkg_file_split = epkg_file.split("__")
        epkg_name_version = "{0}-{1}".format(epkg_file_split[1],
                                             epkg_file_split[2])
        epkg_pkg_version.append(epkg_name_version)
    for rpm in rpm_list:
        rpm_name_map = {}
        rpm_file_split = rpm.rsplit("-", 1)
        rpm_pkg_version.append(rpm_file_split[0])
        rpm_name_map[rpm_file_split[0]] = rpm_file_split[1]
        rpm_name_map_list.append(rpm_name_map)
    tmp_batch_list = list(set(rpm_pkg_version) - set(epkg_pkg_version))
    for name_map in rpm_name_map_list:
        if list(name_map.keys())[0] in tmp_batch_list:
            rpm_name = "{0}-{1}".format(list(name_map.keys())[0],
                                        list(name_map.values())[0])
            batch_list.append(rpm_name)
    return batch_list


def download_rpm(args):
    print("start parse baseurl")
    rpm_url = args.rpm_url
    arch = args.arch
    strategy = args.strategy
    repo_url = "{0}/{1}/Packages".format(rpm_url,arch)
    download_dir = args.tmp_dir
    os_type = os.environ.get("os", "")
    os_version = os.environ.get("os_version", "")
    channel = os.environ.get("channel", "")
    epkgpkg_dir = "/lkp/{0}/{1}/{2}/epkg".format(os_type, os_version, arch)
    result_root = os.environ.get("result_root", "")
    repo_name = os.path.basename(rpm_url)
    epkg_result_root = "/epkg/channel/{0}/{1}/{2}".format(
        channel, repo_name, arch
    )
    rpm_list = get_rpm_list(repo_url)
    if strategy == "delta":
        # update场景
        dir_exists_flag, epkg_file_list =  check_epkg_tmp_repodir()
        if (dir_exists_flag and epkg_file_list 
            and epkg_file_list is not None):
                batch_list = get_batch_rpm_list(rpm_list, epkg_file_list)
        elif (not dir_exists_flag and not epkg_file_list
                and epkg_file_list is not None):
                batch_list = rpm_list
        else:
            print("获取rpm包列表异常")
            sys.exit(1)
    else:
        batch_list = rpm_list
        # count = 0
    for rpm in batch_list:
        command = ["wget", "-P", "{0}".format(download_dir),
                   "{0}/{1}".format(repo_url, rpm)]
        result = subprocess.run(command, stdout=sys.stdout,
                                stderr=sys.stderr, text=True)
        if result.returncode != 0:
            print("下载rpm包异常")
            continue
        sleep(2)  # 间隔下载,避免占满带宽
        #  下载一个转换一个，回传之后删除对应包，避免执行机空间占满
        print("调用epkg_translate")
        translate_cmd = ["python3", "epkg_translate.py", "-in_repo_dir",
                        "{0}".format(download_dir), "-rpm_name", "{0}".format(rpm)]
        translate_result = subprocess.run(translate_cmd, stdout=sys.stdout,
                                        stderr=sys.stderr, text=True)
        if translate_result.returncode != 0:
            print("epkg包转换失败")
        else:
            # 转换成功的包进行回传
            print("调用result_deal")
            result_deal_cmd = ["python3", "result_deal.py", "-postback_dir",
                               "{0}".format(epkg_result_root),
                               "-epkg_dir", "{0}".format(epkgpkg_dir),
                               "-rpm_dir", "{0}".format(download_dir)]
            result_deal = subprocess.run(result_deal_cmd, stdout=subprocess.PIPE,
                                         stderr=subprocess.PIPE)
            print("Output:", result_deal.stdout.decode())
            print("Error:", result_deal.stderr.decode())
            if result_deal.returncode != 0:
                print("回传处理失败")
            else:
                print("finished processing")
            # count += 1
            # if count >= 5:
            #     break
    return 0


if __name__=="__main__":
    parser = argparse.ArgumentParser(description="下载rpm包")
    parser.add_argument("-rpm_url", required=True, default="", help="rpm_url")
    parser.add_argument("-arch", required=True, default="", help="arch")
    parser.add_argument("-strategy", required=True, default="",
                        help="strategy")
    parser.add_argument("-tmp_dir", required=True, default="", help="tmp_dir")

    args = parser.parse_args()
    ret = download_rpm(args)
    if ret != 0:
        sys.exit(1)
